package com.mdsi.db;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Calendar;
import java.util.GregorianCalendar;

import com.mdsi.models.Person;
import com.mdsi.models.Secretary;
import com.mdsi.models.Student;
import com.mdsi.models.Teacher;


public abstract class Authenticator {
	
	private static String cryptPass (String pass) {
		return pass ;
	}
	
	public static class NoUserFound extends Exception {
		
		/**
		 * 
		 */
		private static final long serialVersionUID = 1L;
	
	}
	
	public static class BadPassword extends Exception {
		
		/**
		 * 
		 */
		private static final long serialVersionUID = 1L;
	
	}
	
	/**
	 * Try to "authenticate" the user, i.e check if email match password in the DB.
	 * 
	 * @param email The user email
	 * @param pass The user password
	 * @return The type of user authenticated
	 * @throws SQLException 
	 * @throws BadPassword if the password isn't correct
	 * @throws NoUserFound if there is no user found with 
	 */
	public static Person authenticate (String email, String pass) throws SQLException, NoUserFound, BadPassword {
		Connection conn = ConnectionManager.getConnection() ;
		// Check for student
		pass = cryptPass(pass) ;
		final String sqlRequest = "SELECT * FROM MDSI_USER.xxx WHERE EMAIL=?" ;
		PreparedStatement st = conn.prepareStatement(sqlRequest.replaceFirst("xxx", "STUDENT")) ;
		st.setString(1, email) ;
		ResultSet result = st.executeQuery() ;
		if (result.next()) {
			if (!result.getString("PASS").equals(pass)) {
				conn.close () ;
				throw new BadPassword() ;
			}
			Calendar birthdate = GregorianCalendar.getInstance() ;
			birthdate.setTime(result.getDate("BIRTHDATE")) ;
			Student student =
				new Student(result.getLong("ID_STUDENT"), 
					result.getString("FIRSTNAME"), 
					result.getString("LASTNAME"),
					result.getString("EMAIL"), 
					result.getLong("NUM"), 
					birthdate, 
					result.getString("NATIONALITY")) ;
			conn.close () ;
			return student ;
		}
		st = conn.prepareStatement(sqlRequest.replaceFirst("xxx", "TEACHER")) ;
		st.setString(1, email) ;
		result = st.executeQuery() ;
		if (result.next()) {
			if (!result.getString("PASS").equals(pass)) {
				conn.close () ;
				throw new BadPassword() ;
			}
			Teacher teacher =
				new Teacher(result.getLong("ID_TEACHER"), 
					result.getString("FIRSTNAME"), 
					result.getString("LASTNAME"),
					result.getString("EMAIL"), 
					result.getLong("IMMAT"),
					Teacher.StatutType.valueOf(result.getString("STATUT")),
					result.getString("FUNCT")) ;
			conn.close () ;
			return teacher ;
		}
		st = conn.prepareStatement(sqlRequest.replaceFirst("xxx", "SECRETARY")) ;
		st.setString(1, email) ;
		result = st.executeQuery() ;
		if (result.next()) {
			if (!result.getString("PASS").equals(pass)) {
				conn.close () ;
				throw new BadPassword() ;
			}
			Calendar hiredate = GregorianCalendar.getInstance() ;
			hiredate.setTime(result.getDate("HIRE_DATE")) ;
			Secretary secretary =  new Secretary (result.getLong("ID_SECRETARY"), 
					result.getString("FIRSTNAME"), 
					result.getString("LASTNAME"),
					result.getString("EMAIL"), 
					result.getLong("IMMAT"),
					Secretary.StatutType.valueOf(result.getString("STATUT")),
					hiredate) ;
			conn.close () ;
			return secretary ;
		}
		conn.close() ;
		throw new NoUserFound() ;
	}

}
